﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Research.Kinect.Nui;

namespace IntelBillboard
{
    class GestureController
    {
        const float DELTA = 0.2f;
        DateTime select_check_time = DateTime.MaxValue;
        Microsoft.Research.Kinect.Nui.Vector selectPreRP = new Microsoft.Research.Kinect.Nui.Vector();

        /*------------------------------private helper methods-------------------------------------------*/

        public bool isZeroVector(Microsoft.Research.Kinect.Nui.Vector aVector)
        {
            if (aVector.X == 0 && aVector.Y == 0 && aVector.Z == 0)
                return true;
            else
                return false;
        }

        public bool isApproxEqualVector2(Microsoft.Research.Kinect.Nui.Vector vectorA, Microsoft.Research.Kinect.Nui.Vector vectorB, float delta)
        {
            if (isApproxEqual2(vectorA.X, vectorB.X, delta) && isApproxEqual2(vectorA.Y, vectorB.Y, delta) && isApproxEqual2(vectorA.Z, vectorB.Z, delta))
                return true;

            return false;
        }

        public bool isApproxEqual3(float a, float b, float c, float delta)
        {
            return Math.Abs(a - b) <= delta && Math.Abs(b - c) <= delta && Math.Abs(a - c) <= delta;
        }

        public bool isApproxEqual2(float a, float b, float delta)
        {
            return Math.Abs(a - b) <= delta;
        }


        /*------------------------------gesture detection methods-------------------------------------------*/

        /*
         * Return true if right hand holds at a position for 3 senconds
         * Global Variables: select_check_time; starting time to check
         *                   selectPreRP; previous right hand position
         */
        public bool checkSelect(JointsCollection joints)
        {
            Microsoft.Research.Kinect.Nui.Vector HandRP = joints[JointID.HandRight].Position;
            Microsoft.Research.Kinect.Nui.Vector SpineP = joints[JointID.Spine].Position;

            if (isZeroVector(selectPreRP))
            {
                selectPreRP = HandRP;
            }

            // if hand is in front of the body
            if ((SpineP.Z - HandRP.Z) > 0.2f && isApproxEqualVector2(HandRP, selectPreRP, DELTA))
            {
                if (select_check_time == DateTime.MaxValue)
                {
                    select_check_time = DateTime.Now;
                }
                else
                {
                    DateTime cur_time = DateTime.Now;
                    if (cur_time.Subtract(select_check_time) > TimeSpan.FromSeconds(2))
                    {
                        select_check_time = DateTime.MaxValue;
                        selectPreRP.X = 0;
                        selectPreRP.Y = 0;
                        selectPreRP.Z = 0;
                        return true;
                    }
                }
            }
            else
            {
                select_check_time = DateTime.MaxValue;
                selectPreRP.X = 0;
                selectPreRP.Y = 0;
                selectPreRP.Z = 0;
            }

            return false;
        }

        /*
         * Return true if:
         * 1) right knee is on the left and in front of left knee 
         * 2) right foot is on the right of left foot
         */
        public bool checkFemale(JointsCollection joints)
        {
            Microsoft.Research.Kinect.Nui.Vector KneeR = joints[JointID.KneeRight].Position;
            Microsoft.Research.Kinect.Nui.Vector KneeL = joints[JointID.KneeLeft].Position;
            Microsoft.Research.Kinect.Nui.Vector FootR = joints[JointID.FootRight].Position;
            Microsoft.Research.Kinect.Nui.Vector FootL = joints[JointID.FootLeft].Position;

            if (KneeR.X < KneeL.X && KneeR.Z < KneeL.Z && FootR.X > FootL.X)
                return true;
            else
                return false;
        }

        /*
         * Return true if:
         * 1) right shoulder and right elbow at the same vertical level: Y equal
         * 2) right elbow and right wrist at the same horizontal level: X equal
         * 3) right wrist is above elbow
         * 4) left hand gesture doesn't fit the above condition
         */
        public bool checkMale(JointsCollection joints)
        {
            Microsoft.Research.Kinect.Nui.Vector WristLP = joints[JointID.WristLeft].Position;
            Microsoft.Research.Kinect.Nui.Vector ElbowLP = joints[JointID.ElbowLeft].Position;
            Microsoft.Research.Kinect.Nui.Vector ShoulderLP = joints[JointID.ShoulderLeft].Position;
            Microsoft.Research.Kinect.Nui.Vector WristRP = joints[JointID.WristRight].Position;
            Microsoft.Research.Kinect.Nui.Vector ElbowRP = joints[JointID.ElbowRight].Position;
            Microsoft.Research.Kinect.Nui.Vector ShoulderRP = joints[JointID.ShoulderRight].Position;

            // check left arm
            bool b1 = isApproxEqual3(ShoulderLP.Z, WristLP.Z, ElbowLP.Z, DELTA)
                && isApproxEqual2(WristLP.X, ElbowLP.X, DELTA) && ElbowLP.X < ShoulderLP.X
                && isApproxEqual2(ElbowLP.Y, ShoulderLP.Y, DELTA) && WristLP.Y > ElbowLP.Y;

            // check right arm
            bool b2 = isApproxEqual3(ShoulderRP.Z, WristRP.Z, ElbowRP.Z, DELTA)
                && isApproxEqual2(WristRP.X, ElbowRP.X, DELTA) && ElbowRP.X > ShoulderRP.X
                && isApproxEqual2(ElbowRP.Y, ShoulderRP.Y, DELTA) && WristRP.Y > ElbowRP.Y;

            if (b2 && !b1)
                return true;
            else
                return false;
        }

        /*
         * Return true if both hands fullfill the calibration gesture criteria:
         * 1) shoulder and elbow at the same vertical level: Y equal
         * 2) elbow and wrist at the same horizontal level: X equal
         * 3) wrist is above elbow
         * 4) elbow is outside of shoulder 
         * 5) shoulder, elbow and wrist are at the same depth: Z equal
         */
        public bool checkCalibration(JointsCollection joints)
        {
            Microsoft.Research.Kinect.Nui.Vector WristLP = joints[JointID.WristLeft].Position;
            Microsoft.Research.Kinect.Nui.Vector ElbowLP = joints[JointID.ElbowLeft].Position;
            Microsoft.Research.Kinect.Nui.Vector ShoulderLP = joints[JointID.ShoulderLeft].Position;
            Microsoft.Research.Kinect.Nui.Vector WristRP = joints[JointID.WristRight].Position;
            Microsoft.Research.Kinect.Nui.Vector ElbowRP = joints[JointID.ElbowRight].Position;
            Microsoft.Research.Kinect.Nui.Vector ShoulderRP = joints[JointID.ShoulderRight].Position;

            // check left arm
            bool b1 = isApproxEqual3(ShoulderLP.Z, WristLP.Z, ElbowLP.Z, DELTA)
                && isApproxEqual2(WristLP.X, ElbowLP.X, DELTA) && ElbowLP.X < ShoulderLP.X
                && isApproxEqual2(ElbowLP.Y, ShoulderLP.Y, DELTA) && WristLP.Y > ElbowLP.Y;
            // check right arm
            bool b2 = isApproxEqual3(ShoulderRP.Z, WristRP.Z, ElbowRP.Z, DELTA)
                && isApproxEqual2(WristRP.X, ElbowRP.X, DELTA) && ElbowRP.X > ShoulderRP.X
                && isApproxEqual2(ElbowRP.Y, ShoulderRP.Y, DELTA) && WristRP.Y > ElbowRP.Y;
            // check two arm balance
            bool b3 = isApproxEqual2(ShoulderLP.Y, ShoulderRP.Y, DELTA);

            if (b1 && b2 && b3)
                return true;

            return false;
        }

        /*
         *  Return true when right hand swap horizontally to the right for a certain amount
         */
        public bool checkSwapRight(List<SkeletonData> skeletonHistory)
        {
            int framesToCheck = 10;

            // Create a local copy as skeleton history gets updated every ~1/30 th of a second
            List<SkeletonData> localSkeletonHistory = new List<SkeletonData>(skeletonHistory);

            // if don't have enough frames to check in the history list
            if (localSkeletonHistory.Count < framesToCheck)
            {
                return false;
            }

            for (int i = localSkeletonHistory.Count - framesToCheck + 1; i < localSkeletonHistory.Count; i++)
            {
                // left hand should be in front the body, hand above wrist and elbow
                if (!(localSkeletonHistory[i].Joints[JointID.HandRight].Position.Z < localSkeletonHistory[i].Joints[JointID.ShoulderCenter].Position.Z
                    && localSkeletonHistory[i].Joints[JointID.HandRight].Position.Y > localSkeletonHistory[i].Joints[JointID.WristRight].Position.Y
                    && localSkeletonHistory[i].Joints[JointID.HandRight].Position.Y > localSkeletonHistory[i].Joints[JointID.ElbowRight].Position.Y))
                    return false;

                // check if hand is moving to the right
                if (!(isApproxEqual2(localSkeletonHistory[i].Joints[JointID.HandRight].Position.Y, localSkeletonHistory[i - 1].Joints[JointID.HandRight].Position.Y, DELTA)
                   && localSkeletonHistory[i].Joints[JointID.HandRight].Position.X > localSkeletonHistory[i - 1].Joints[JointID.HandRight].Position.X))
                    return false;
            }

            //check if moving distance is long enough
            float refDistance = Math.Abs(localSkeletonHistory[0].Joints[JointID.Spine].Position.Y - localSkeletonHistory[0].Joints[JointID.HipCenter].Position.Y);
            float rightHandStartPosX = localSkeletonHistory[localSkeletonHistory.Count - framesToCheck].Joints[JointID.HandRight].Position.X;
            float rightHandEndPosX = localSkeletonHistory[localSkeletonHistory.Count - 1].Joints[JointID.HandRight].Position.X;

            if (rightHandEndPosX - rightHandStartPosX > refDistance * 3)
            {
                skeletonHistory.Clear();
                return true;
            }
            else
            {
                Console.WriteLine("Right swap distance too short");
                return false;
            }
        }

        /*
         *  Return true when right hand swap horizontally to the left for a certain amount
         */
        public bool checkSwapLeft(List<SkeletonData> skeletonHistory)
        {
            int framesToCheck = 10;

            // Create a local copy as skeleton history gets updated every ~1/30 th of a second
            List<SkeletonData> localSkeletonHistory = new List<SkeletonData>(skeletonHistory);

            // if don't have enough frames to check in the history list
            if (localSkeletonHistory.Count < framesToCheck)
            {
                return false;
            }

            for (int i = localSkeletonHistory.Count - framesToCheck + 1; i < localSkeletonHistory.Count; i++)
            {
                // left hand should be in front the body, hand above wrist and elbow
                if (!(localSkeletonHistory[i].Joints[JointID.HandRight].Position.Z < localSkeletonHistory[i].Joints[JointID.ShoulderCenter].Position.Z
                    && localSkeletonHistory[i].Joints[JointID.HandRight].Position.Y > localSkeletonHistory[i].Joints[JointID.ElbowRight].Position.Y))
                    return false;

                // check if hand is moving to the left
                if (!(isApproxEqual2(localSkeletonHistory[i].Joints[JointID.HandRight].Position.Y, localSkeletonHistory[i - 1].Joints[JointID.HandRight].Position.Y, DELTA)
                   && localSkeletonHistory[i].Joints[JointID.HandRight].Position.X < localSkeletonHistory[i - 1].Joints[JointID.HandRight].Position.X))
                    return false;
            }

            //check if moving distance is long enough
            float refDistance = Math.Abs(localSkeletonHistory[0].Joints[JointID.Spine].Position.Y - localSkeletonHistory[0].Joints[JointID.HipCenter].Position.Y);
            float rightHandStartPosX = localSkeletonHistory[localSkeletonHistory.Count - framesToCheck].Joints[JointID.HandRight].Position.X;
            float rightHandEndPosX = localSkeletonHistory[localSkeletonHistory.Count - 1].Joints[JointID.HandRight].Position.X;

            if (rightHandStartPosX - rightHandEndPosX > refDistance * 3)
            {
                skeletonHistory.Clear();
                return true;
            }
            else
            {
                Console.WriteLine("Left swap distance too short");
                return false;
            }
        }

        /*
        * This method returns boolean value to indicate whether the player has kicked using the right foot
        */
        public bool checkRightKicking(List<SkeletonData> skeletonHistory)
        {
            /*
             * The conditions for right foot kicking to be true:
             *   1.	Right foot has moved to the front of the starting position by half of the reference distance, which is the distance from hip center to spine.
             *   2.	Right knee has moved to the front of the starting position.
             *   3.	Right foot has moved to the front of previous frame by quarter of the reference distance.
             *   4.	Right knee has moved to the front of previous frame.
             *   5.	Right foot has moved to a higher position than the previous frame. 
             *
             */

            // the max length of time the gesture can take
            int gesturePeriod = 1;
            int indexesPerSecond = 8;
            int indexesToCheck = gesturePeriod * indexesPerSecond;

            // Create a local copy as skeleton history gets updated every ~1/30 th of a second
            List<SkeletonData> localSkeletonHistory = new List<SkeletonData>(skeletonHistory);

            // if you don’t have enough frames to look at
            if (localSkeletonHistory.Count < indexesToCheck)
            {
                return false;
            }

            float refDistance = Math.Abs(localSkeletonHistory[0].Joints[JointID.KneeRight].Position.Y - localSkeletonHistory[0].Joints[JointID.FootRight].Position.Y);
            float startPosFoot = localSkeletonHistory[localSkeletonHistory.Count - indexesToCheck].Joints[JointID.FootRight].Position.Z;
            float startPosKnee = localSkeletonHistory[localSkeletonHistory.Count - indexesToCheck].Joints[JointID.KneeRight].Position.Z;

            bool kicking = false;

            for (int i = localSkeletonHistory.Count - indexesToCheck + 1; i < localSkeletonHistory.Count; i++)
            {
                if (localSkeletonHistory[i].Joints[JointID.FootRight].Position.Z < startPosFoot - refDistance / 3 &&
                    localSkeletonHistory[i].Joints[JointID.KneeRight].Position.Z < startPosKnee &&
                    localSkeletonHistory[i].Joints[JointID.FootRight].Position.Z < localSkeletonHistory[i - 1].Joints[JointID.FootRight].Position.Z - refDistance / 3 &&
                    localSkeletonHistory[i].Joints[JointID.KneeRight].Position.Z < localSkeletonHistory[i - 1].Joints[JointID.KneeRight].Position.Z &&
                    localSkeletonHistory[i].Joints[JointID.FootRight].Position.Y > localSkeletonHistory[i - 1].Joints[JointID.FootRight].Position.Y &&
                    !kicking)
                {
                    kicking = true;
                    skeletonHistory.Clear();
                    return true;
                }
            }
            return false;
        }

        public bool checkRightHandUp(List<SkeletonData> skeletonHistory)
        {
            /*
             * The conditions for right hand up to be true:
             *  
             *   1.	Right hand is below hip right at first
             *   2.	Right hand's Y value should be larger than the hip right's Y at the last index of the local histoy
             *
             */

            // the max length of time the gesture can take
            int gesturePeriod = 1;
            int indexesPerSecond = 8;
            int indexesToCheck = gesturePeriod * indexesPerSecond;


            // Create a local copy as skeleton history gets updated every ~1/30 th of a second
            List<SkeletonData> localSkeletonHistory = new List<SkeletonData>(skeletonHistory);

            // if you don’t have enough frames to look at
            if (localSkeletonHistory.Count < indexesToCheck)
            {
                return false;
            }


            /*
             for (int i = localSkeletonHistory.Count - indexesToCheck + 1; i < localSkeletonHistory.Count; i++)
             {
                
                 if (localSkeletonHistory[i].Joints[JointID.HandRight].Position.Y < localSkeletonHistory[i - 1].Joints[JointID.HandRight].Position.Y)
                     return false;             
                              
             }
             */
            if (localSkeletonHistory[localSkeletonHistory.Count - 1].Joints[JointID.HandLeft].Position.Y > localSkeletonHistory[localSkeletonHistory.Count - 1].Joints[JointID.HipLeft].Position.Y)
                return false;

            if (localSkeletonHistory[localSkeletonHistory.Count - indexesToCheck].Joints[JointID.HandRight].Position.Y > localSkeletonHistory[localSkeletonHistory.Count - indexesToCheck].Joints[JointID.HipRight].Position.Y)
                return false;

            if (localSkeletonHistory[localSkeletonHistory.Count - 1].Joints[JointID.HandRight].Position.Y < localSkeletonHistory[localSkeletonHistory.Count - 1].Joints[JointID.Head].Position.Y)
                return false;


            return true;

        }

        public bool checkLeftHandUp(List<SkeletonData> skeletonHistory)
        {
            /*
             * The conditions for left hand up to be true:
             *  
             *   1.	Left hand's Y value is constantly increasing
             *   2.	Left hand's Y value should be larger than the hip left's Y at the last index of the local histoy
             *
             */

            // the max length of time the gesture can take
            int gesturePeriod = 1;
            int indexesPerSecond = 10;
            int indexesToCheck = gesturePeriod * indexesPerSecond;


            // Create a local copy as skeleton history gets updated every ~1/30 th of a second
            List<SkeletonData> localSkeletonHistory = new List<SkeletonData>(skeletonHistory);

            // if you don’t have enough frames to look at
            if (localSkeletonHistory.Count < indexesToCheck)
            {
                return false;
            }

            if (localSkeletonHistory[localSkeletonHistory.Count - 1].Joints[JointID.HandRight].Position.Y > localSkeletonHistory[localSkeletonHistory.Count - 1].Joints[JointID.HipRight].Position.Y)
                return false;

            if (localSkeletonHistory[localSkeletonHistory.Count - indexesToCheck].Joints[JointID.HandLeft].Position.Y > localSkeletonHistory[localSkeletonHistory.Count - indexesToCheck].Joints[JointID.HipLeft].Position.Y)
                return false;


            if (localSkeletonHistory[localSkeletonHistory.Count - 1].Joints[JointID.HandLeft].Position.Y < localSkeletonHistory[localSkeletonHistory.Count - 1].Joints[JointID.Head].Position.Y)
                return false;


            return true;

        }

        public bool checkMoveToLeft(List<SkeletonData> skeletonHistory)
        {
            /*
             * The conditions for left hand up to be true:
             *  
             *   1.	Left hand's Y value is constantly increasing
             *   2.	Left hand's Y value should be larger than the hip left's Y at the last index of the local histoy
             *
             */

            // the max length of time the gesture can take
            int gesturePeriod = 1;
            int indexesPerSecond = 10;
            int indexesToCheck = gesturePeriod * indexesPerSecond;


            // Create a local copy as skeleton history gets updated every ~1/30 th of a second
            List<SkeletonData> localSkeletonHistory = new List<SkeletonData>(skeletonHistory);

            // if you don’t have enough frames to look at
            if (localSkeletonHistory.Count < indexesToCheck)
            {
                return false;
            }

            if (localSkeletonHistory[localSkeletonHistory.Count - indexesToCheck + 1].Joints[JointID.HipCenter].Position.X - localSkeletonHistory[localSkeletonHistory.Count - 1].Joints[JointID.HipCenter].Position.X < 0.18)
                return false;



            for (int i = localSkeletonHistory.Count - indexesToCheck + 1; i < localSkeletonHistory.Count - 1; i++)
            {

                if (localSkeletonHistory[i].Joints[JointID.HipCenter].Position.X < localSkeletonHistory[i + 1].Joints[JointID.HipCenter].Position.X)
                    return false;

            }


            return true;

        }

        public bool checkMoveToRight(List<SkeletonData> skeletonHistory)
        {
            /*
             * The conditions for left hand up to be true:
             *  
             *    dynamically move to right over a distance 
             *
             */

            // the max length of time the gesture can take
            int gesturePeriod = 1;
            int indexesPerSecond = 10;
            int indexesToCheck = gesturePeriod * indexesPerSecond;


            // Create a local copy as skeleton history gets updated every ~1/30 th of a second
            List<SkeletonData> localSkeletonHistory = new List<SkeletonData>(skeletonHistory);

            // if you don’t have enough frames to look at
            if (localSkeletonHistory.Count < indexesToCheck)
            {
                return false;
            }

            if (localSkeletonHistory[localSkeletonHistory.Count - 1].Joints[JointID.HipCenter].Position.X - localSkeletonHistory[localSkeletonHistory.Count - indexesToCheck + 1].Joints[JointID.HipCenter].Position.X < 0.18)
                return false;



            for (int i = localSkeletonHistory.Count - indexesToCheck + 1; i < localSkeletonHistory.Count - 1; i++)
            {

                if (localSkeletonHistory[i].Joints[JointID.HipCenter].Position.X > localSkeletonHistory[i + 1].Joints[JointID.HipCenter].Position.X)
                    return false;

            }


            return true;

        }

        /*
         * 
         * checkChildren() is to detect children passers-by
         * 
         */

        public bool checkChildren(List<SkeletonData> skeletonHistory)
        {

            int indexesToCheck = 10;

            // Create a local copy as skeleton history gets updated every ~1/30 th of a second

            List<SkeletonData> localSkeletonHistory = new List<SkeletonData>(skeletonHistory);

            // if there is no enough frames to look at, return false

            if (localSkeletonHistory.Count <= indexesToCheck)
            {

                return false;
            }

            //int startPoint = localSkeletonHistory.Count - indexesToCheck-1;
            float startRightFootY = localSkeletonHistory[localSkeletonHistory.Count - indexesToCheck - 1].Joints[JointID.FootRight].Position.Y;
            float startLeftFootY = localSkeletonHistory[localSkeletonHistory.Count - indexesToCheck - 1].Joints[JointID.FootLeft].Position.Y;
            float startCenterHipY = localSkeletonHistory[localSkeletonHistory.Count - indexesToCheck - 1].Joints[JointID.HipCenter].Position.Y;
            float startCenterHipZ = localSkeletonHistory[localSkeletonHistory.Count - indexesToCheck - 1].Joints[JointID.HipCenter].Position.Z;

            float currentRightFootY = localSkeletonHistory[localSkeletonHistory.Count - 1].Joints[JointID.FootRight].Position.Y;
            float currentLeftFootY = localSkeletonHistory[localSkeletonHistory.Count - 1].Joints[JointID.FootLeft].Position.Y;
            float currentCenterHipY = localSkeletonHistory[localSkeletonHistory.Count - 1].Joints[JointID.HipCenter].Position.Y;
            float currentCenterHipZ = localSkeletonHistory[localSkeletonHistory.Count - 1].Joints[JointID.HipCenter].Position.Z;

            // for (int i = localSkeletonHistory.Count - indexesToCheck + 1; i < localSkeletonHistory.Count; i++)
            // {


            //throughout the upwords process, check whether the foot is always moving upword
            // if (localSkeletonHistory[i].Joints[JointID.FootLeft].Position.Y <= localSkeletonHistory[i - 1].Joints[JointID.FootLeft].Position.Y)
            //  Console.Write("not continuous");
            //  return false;


            //  }

            if ((currentRightFootY - startRightFootY) > 0.02 && (currentLeftFootY - startLeftFootY) > 0.02
                && (currentCenterHipY - startCenterHipY) > 0.02)

                return true;
            else

                return false;



        }


        /*
         * 
         * Check for Push gesture(dynamic) use for selection
         * 
         */

        public bool checkSelectPush(List<SkeletonData> skeletonHistory)
        {
            int framesToCheck = 20;
            float currentFrame = 0;
            float previousFrame = 0;
            float sum = 0;

            // Create a local copy as skeleton history gets updated every ~1/30 th of a second
            List<SkeletonData> localSkeletonHistory = new List<SkeletonData>(skeletonHistory);

            // if don't have enough frames to check in the history list
            if (localSkeletonHistory.Count < framesToCheck)
            {
                return false;
            }

            for (int i = localSkeletonHistory.Count - framesToCheck + 1; i < localSkeletonHistory.Count; i++)
            {

                int initialFrame = localSkeletonHistory.Count - framesToCheck + 1;
                // left hand should be in front the body, hand above wrist and elbow
                if (localSkeletonHistory[i].Joints[JointID.HandRight].Position.Y < localSkeletonHistory[i].Joints[JointID.Head].Position.Y &&
                    localSkeletonHistory[i].Joints[JointID.HandRight].Position.Y > localSkeletonHistory[i].Joints[JointID.HipCenter].Position.Y)
                {

                    if (isApproxEqual2(localSkeletonHistory[initialFrame].Joints[JointID.HandRight].Position.X,
                        localSkeletonHistory[i].Joints[JointID.HandRight].Position.X, 0.05f) &&
                        isApproxEqual2(localSkeletonHistory[initialFrame].Joints[JointID.HandRight].Position.Y,
                        localSkeletonHistory[i].Joints[JointID.HandRight].Position.Y, 0.05f))
                    {
                        //taking the Z co-ords of the latest frame and previous frame
                        currentFrame = localSkeletonHistory[i].Joints[JointID.HandRight].Position.Z;
                        previousFrame = localSkeletonHistory[i - 1].Joints[JointID.HandRight].Position.Z;

                        //sum up the difference between the Z co-ords
                        //if right hand moves in direction Z for 0.4f, Push gesture is activated
                        if (sum < 0.4f)
                        {
                            sum += currentFrame - previousFrame;
                        }
                        else
                        {
                            sum = 0;
                            return true;
                        }

                    }
                    else
                        return false;
                }

                else
                {
                    return false;
                }

            }

            return false;

        }









    }

}
